package com.xu.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * SpringMVC 的视图
 *
 * SpringMVC 中的视图是 View 接口，视图的作用渲染数据，将模型 Model 中的数据展示给用户，SpringMVC 视图的种类很多，
 * 默认有转发视图和重定向视图。若使用的视图技术为 Thymeleaf，在 SpringMVC 的配置文件中配置了 Thymeleaf 的视图解析器，由此视
 * 图解析器解析之后所得到的是 ThymeleafView。
 *
 * 1. ThymeleafView
 *
 * 当控制器方法中所设置的视图名称没有任何前缀时，此时的视图名称会被 SpringMVC 配置文件中所配置的视图解析器解析，视图名称拼接
 * 视图前缀和视图后缀所得到的最终路径，会通过转发的方式实现跳转
 *
 * 2. 转发视图
 *
 * SpringMVC 中默认的转发视图是 InternalResourceView。SpringMVC 中创建转发视图的情况：
 * 当控制器方法中所设置的视图名称以 "forward:" 为前缀时，创建 InternalResourceView 视图，此时的视图名称不会被 SpringMVC 配置
 * 文件中所配置的视图解析器解析，而是会将前缀 "forward:" 去掉，剩余部分作为最终路径通过转发的方式实现跳转例如：
 * "forward:/employee"，这里是跳转到 /employee 这个 Controller 处理器处理
 *
 * 3. 重定向视图
 *
 * SpringMVC 中默认的重定向视图是 RedirectView。当控制器方法中所设置的视图名称以 "redirect:" 为前缀时，创建 RedirectView 视图，
 * 此时的视图名称不会被 SpringMVC 配置文件中所配置的视图解析器解析，而是会将前缀 "redirect:" 去掉，剩余部分作为最
 * 终路径通过重定向的方式实现跳转例如 "redirect:/"，"redirect:/employee"
 *
 * 4. redirect 和 forward 的区别：
 *
 * forward 转发，如 return "forward:/hello"; 浏览器的地址栏不会变，但是通常会有新的视图页面
 * redirect 重定向，如 return "redirect:/hello"; 浏览器的地址栏会变
 *
 * 4.1 redirect：相当于 "response.sendRedirect()" 这种方式外部特征就是浏览器地址栏最后显示的路径是转发后的新的路径。
 *     工作方式：服务器端会首先发一个 response 给浏览器, 然后浏览器收到这个 response 后再发一个 request 给服务器,
 *              然后服务器发新的 response 给浏览器. 这时页面收到的 request 是一个新从浏览器发来的。
 *     这种方式的结果是：在转发前后有两个不同的 request 对象,转发前后的两个控制器在 request 上的参数 (request.getParameter())
 *                      和 request 属性 (request.getAttribute()) 不能共享; 如果转发前后的两个控制器都配置在 spring 拦截器范
 *                      围内，这样拦截器会拦截前后两个 request，即会拦截两次;最后返回到浏览器后,因为地址栏显示的是转发后的 url,
 *                      所以刷新页面时只会执行后面的 url 映射的控制器.
 *
 * 4.2 forward：相当于 request.getRequestDispatcher().forward(request,response)。这种方式的外部特征是浏览器地址显示的路径是
 *              转发前的路径.
 *    工作方式：forward 发生在服务器内部，在前一个控制器处理完毕后，直接进入下一个控制器处理, 并将最后的 response 发给浏览器。
 *    这种方式的结果是：转发前后是同一个 request，后一个控制器可共享前一个控制器的参数与属性; 因为是同一个 request，拦截器只会
 *                     拦截前一个 url，即只拦截一次;最后返回到浏览器后,因为地址栏显示的是转发前的 url,所以刷新页面时会依次执
 *                     行前后两个控制器.
 *
 * 5. 视图控制器 view-controller：当控制器方法中，仅仅用来实现页面跳转，即只需要设置视图名称时，可以将处理器方法使用
 * view-controller 标签进行表示。当 SpringMVC 中设置任何一个 view-controller 时，其他控制器中的请求映射将全部失效，此时需
 * 要在 SpringMVC 的核心配置文件中设置开启 mvc 注解驱动的标签：<mvc:annotation-driven />
 */

@Controller
public class HelloController {

    @RequestMapping("/")
    public String index(){
        // 返回视图名称，即加上配置视图解析器时，指定的前缀和后缀
        return "index";
    }

    @RequestMapping("/target")
    public String toTarget(){
        return "target";
    }

}
